from django.core.exceptions import ObjectDoesNotExist
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.views import APIView
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi

from .models import FontCategory, Font
from .serializers import (
    FontCategorySerializer,
    CreateFontCategorySerializer,
    UpdateFontCategorySerializer, FontSerializer, CreateFontSerializer, UpdateFontSerializer
)
from ..utils.response_utils import api_response, ResponseCode


class ListFontCategoriesView(APIView):
    """字体分类列表接口"""

    @swagger_auto_schema(
        operation_description="获取字体分类列表",
        responses={
            200: FontCategorySerializer(many=True),
            500: openapi.Response(description="服务器错误"),
        },
        tags=["字体分类管理"]
    )
    def get(self, request):
        try:
            queryset = FontCategory.objects.all()
            serializer = FontCategorySerializer(queryset, many=True)
            return api_response(ResponseCode.SUCCESS, "获取成功", serializer.data)
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, str(e))


class CreateFontCategoryView(APIView):
    """创建字体分类接口"""

    @swagger_auto_schema(
        operation_description="创建字体分类",
        request_body=CreateFontCategorySerializer,
        responses={
            200: FontCategorySerializer,
            400: openapi.Response(description="参数错误"),
        },
        tags=["字体分类管理"]
    )
    def post(self, request):
        try:
            serializer = CreateFontCategorySerializer(data=request.data)
            if serializer.is_valid():
                category = serializer.save()
                full_serializer = FontCategorySerializer(category)
                return api_response(ResponseCode.SUCCESS, "创建成功", full_serializer.data)
            return api_response(ResponseCode.BAD_REQUEST, f"参数错误：{serializer.errors}")
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, f"服务器错误: {str(e)}")


class UpdateFontCategoryView(APIView):
    """更新字体分类接口"""

    @swagger_auto_schema(
        operation_description="更新字体分类",
        request_body=UpdateFontCategorySerializer,
        manual_parameters=[
            openapi.Parameter('category_id', openapi.IN_PATH, type=openapi.TYPE_STRING,
                              description="字体分类ID")
        ],
        responses={
            200: FontCategorySerializer,
            400: openapi.Response(description="参数错误"),
            404: openapi.Response(description="分类不存在"),
        },
        tags=["字体分类管理"]
    )
    def put(self, request, category_id):
        try:
            category = FontCategory.objects.get(id=category_id)
            serializer = UpdateFontCategorySerializer(category, data=request.data, partial=True)
            if serializer.is_valid():
                updated_category = serializer.save()
                full_serializer = FontCategorySerializer(updated_category)
                return api_response(ResponseCode.SUCCESS, "更新成功", full_serializer.data)
            return api_response(ResponseCode.BAD_REQUEST, f"参数错误：{serializer.errors}")
        except ObjectDoesNotExist:
            return api_response(ResponseCode.NOT_FOUND, "分类不存在")
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, f"服务器错误: {str(e)}")


class DeleteFontCategoryView(APIView):
    """删除字体分类接口"""

    @swagger_auto_schema(
        operation_description="删除字体分类",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['category_ids'],
            properties={
                'category_ids': openapi.Schema(
                    type=openapi.TYPE_ARRAY,
                    items=openapi.Schema(type=openapi.TYPE_STRING),
                    description="分类ID列表"
                ),
            }
        ),
        responses={
            200: openapi.Response(description="删除成功"),
            404: openapi.Response(description="部分分类不存在"),
        },
        tags=["字体分类管理"]
    )
    def delete(self, request):
        category_ids = request.data.get('category_ids', [])
        if not category_ids or not isinstance(category_ids, list):
            return api_response(ResponseCode.BAD_REQUEST, "参数错误")

        not_found_ids = []
        for category_id in category_ids:
            try:
                category = FontCategory.objects.get(id=category_id)
                category.delete()
            except ObjectDoesNotExist:
                not_found_ids.append(category_id)

        if not_found_ids:
            return api_response(
                ResponseCode.NOT_FOUND,
                f"成功删除分类: {len(category_ids) - len(not_found_ids)}个，未找到ID: {', '.join(not_found_ids)}"
            )
        return api_response(ResponseCode.SUCCESS, "删除成功")


class ListFontsView(APIView):
    """字体列表接口"""

    @swagger_auto_schema(
        operation_description="获取字体列表",
        manual_parameters=[
            openapi.Parameter('category_id', openapi.IN_QUERY, type=openapi.TYPE_STRING,
                              description="字体分类ID(可选)", required=False),
        ],
        responses={
            200: FontSerializer(many=True),
            500: openapi.Response(description="服务器错误"),
        },
        tags=["字体管理"]
    )
    def get(self, request):
        try:
            category_id = request.query_params.get('category_id')
            if category_id in ['null', 'undefined', '', None]:
                queryset = Font.objects.all().order_by('-created_at')
            else:
                queryset = Font.objects.filter(category_id=category_id).order_by('-created_at')
            serializer = FontSerializer(queryset, many=True)
            return api_response(ResponseCode.SUCCESS, "获取成功", serializer.data)
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, str(e))


class CreateFontView(APIView):
    """创建字体接口"""
    parser_classes = [MultiPartParser, FormParser]

    @swagger_auto_schema(
        operation_description="创建字体",
        request_body=CreateFontSerializer,
        manual_parameters=[
            openapi.Parameter(
                'font_file',
                openapi.IN_FORM,
                type=openapi.TYPE_FILE,
                description='字体文件'
            ),
            openapi.Parameter(
                'preview_image',
                openapi.IN_FORM,
                type=openapi.TYPE_FILE,
                description='预览图(SVG)'
            )
        ],
        responses={
            200: FontSerializer,
            400: openapi.Response(description="参数错误"),
        },
        tags=["字体管理"]
    )
    def post(self, request):
        try:
            font_file = request.FILES.get('font_file')
            preview_image = request.FILES.get('preview_image')

            serializer = CreateFontSerializer(data=request.data)
            if not serializer.is_valid():
                return api_response(ResponseCode.BAD_REQUEST, f"参数错误：{serializer.errors}")

            font = serializer.save()

            if font_file:
                font.file_url = font_file
            if preview_image:
                font.preview_image = preview_image
            font.save()

            result_serializer = FontSerializer(font)
            return api_response(ResponseCode.SUCCESS, "创建成功", result_serializer.data)
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, f"服务器错误: {str(e)}")


class UpdateFontView(APIView):
    """更新字体接口"""
    parser_classes = [MultiPartParser, FormParser]

    @swagger_auto_schema(
        operation_description="更新字体信息",
        request_body=UpdateFontSerializer,
        manual_parameters=[
            openapi.Parameter('font_id', openapi.IN_PATH, type=openapi.TYPE_STRING,
                              description="字体ID"),
            openapi.Parameter(
                'font_file',
                openapi.IN_FORM,
                type=openapi.TYPE_FILE,
                description='字体文件',
                required=False
            ),
            openapi.Parameter(
                'preview_image',
                openapi.IN_FORM,
                type=openapi.TYPE_FILE,
                description='预览图(SVG)',
                required=False
            )
        ],
        responses={
            200: FontSerializer,
            404: openapi.Response(description="字体不存在"),
            400: openapi.Response(description="参数错误"),
        },
        tags=["字体管理"]
    )
    def put(self, request, font_id):
        try:
            font = Font.objects.get(id=font_id)
            font_file = request.FILES.get('font_file')
            preview_image = request.FILES.get('preview_image')

            serializer = UpdateFontSerializer(font, data=request.data, partial=True)
            if not serializer.is_valid():
                return api_response(ResponseCode.BAD_REQUEST, f"参数错误：{serializer.errors}")

            font = serializer.save()

            if font_file:
                font.file_url = font_file
            if preview_image:
                font.preview_image = preview_image
            font.save()

            result_serializer = FontSerializer(font)
            return api_response(ResponseCode.SUCCESS, "更新成功", result_serializer.data)
        except ObjectDoesNotExist:
            return api_response(ResponseCode.NOT_FOUND, "字体不存在")
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, f"服务器错误: {str(e)}")


class ToggleFontFavoriteView(APIView):
    """切换字体收藏状态接口"""

    @swagger_auto_schema(
        operation_description="切换字体收藏状态",
        manual_parameters=[
            openapi.Parameter('font_id', openapi.IN_PATH, type=openapi.TYPE_STRING,
                              description="字体ID")
        ],
        responses={
            200: FontSerializer,
            404: openapi.Response(description="字体不存在"),
        },
        tags=["字体管理"]
    )
    def post(self, request, font_id):
        try:
            font = Font.objects.get(id=font_id)
            # 切换收藏状态
            font.is_favorite = not font.is_favorite
            font.save()

            serializer = FontSerializer(font)
            return api_response(ResponseCode.SUCCESS,
                                "收藏成功" if font.is_favorite else "取消收藏成功",
                                serializer.data)
        except ObjectDoesNotExist:
            return api_response(ResponseCode.NOT_FOUND, "字体不存在")
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, f"服务器错误: {str(e)}")


class DeleteFontView(APIView):
    """删除字体接口"""

    @swagger_auto_schema(
        operation_description="删除字体",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['font_ids'],
            properties={
                'font_ids': openapi.Schema(
                    type=openapi.TYPE_ARRAY,
                    items=openapi.Schema(type=openapi.TYPE_STRING),
                    description="字体ID列表"
                ),
            }
        ),
        responses={
            200: openapi.Response(description="删除成功"),
            404: openapi.Response(description="部分字体不存在"),
        },
        tags=["字体管理"]
    )
    def delete(self, request):
        font_ids = request.data.get('font_ids', [])
        if not font_ids or not isinstance(font_ids, list):
            return api_response(ResponseCode.BAD_REQUEST, "参数错误")

        not_found_ids = []
        for font_id in font_ids:
            try:
                font = Font.objects.get(id=font_id)
                font.delete()
            except ObjectDoesNotExist:
                not_found_ids.append(font_id)

        if not_found_ids:
            return api_response(
                ResponseCode.NOT_FOUND,
                f"成功删除字体: {len(font_ids) - len(not_found_ids)}个，未找到ID: {', '.join(not_found_ids)}"
            )
        return api_response(ResponseCode.SUCCESS, "删除成功")